package com.yupi.mianshiya.job.cycle;

import cn.hutool.core.collection.CollUtil;
import com.yupi.mianshiya.annotation.DistributedLock;
import com.yupi.mianshiya.esdao.QuestionEsDao;
import com.yupi.mianshiya.mapper.QuestionMapper;
import com.yupi.mianshiya.model.dto.question.QuestionEsDTO;
import com.yupi.mianshiya.model.entity.Question;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 增量同步题目到 es
 *
 * @author <a href="https://github.com/liyupi">程序员鱼皮</a>
 * @from <a href="https://yupi.icu">编程导航知识星球</a>
 */
// todo 取消注释开启任务
//@Component
@Slf4j
public class IncSyncQuestionToEs {

    @Resource
    private QuestionMapper questionMapper;

    @Resource
    private QuestionEsDao questionEsDao;
//    @Resource
//    private RedissonClient redissonClient; // 注入 Redisson 客户端
//
//
//    @Scheduled(fixedRate = 60 * 1000) // 每隔 1 分钟执行一次
//    public void run() {
//        // 获取分布式锁
//        RLock lock = redissonClient.getLock("testLock");
//        try {
//            // 尝试获取锁，等待时间为 10 秒，锁过期时间默认自动续期
//            if (lock.tryLock(10, TimeUnit.SECONDS)) {
//                log.info("Acquired lock, start executing task...");
//
//                // 执行任务逻辑
//                executeTask();
//            } else {
//                log.info("Failed to acquire lock, task skipped.");
//            }
//        } catch (InterruptedException e) {
//            log.error("Error occurred while trying to acquire lock", e);
//            Thread.currentThread().interrupt();
//        } finally {
//            // 释放锁
//            if (lock.isHeldByCurrentThread()) {
//                lock.unlock();
//                log.info("Lock released.");
//            }
//        }
//    }
//
//    private void executeTask() {
//        // 查询近 5 分钟内的数据
//        long FIVE_MINUTES = 5 * 60 * 1000L;
//        Date fiveMinutesAgoDate = new Date(new Date().getTime() - FIVE_MINUTES);
//        List<Question> questionList = questionMapper.listQuestionWithDelete(fiveMinutesAgoDate);
//        if (CollUtil.isEmpty(questionList)) {
//            log.info("No incremental questions to sync.");
//            return;
//        }
//
//        List<QuestionEsDTO> questionEsDTOList = questionList.stream()
//                .map(QuestionEsDTO::objToDto)
//                .collect(Collectors.toList());
//        final int pageSize = 500;
//        int total = questionEsDTOList.size();
//        log.info("IncSyncQuestionToEs start, total {}", total);
//
//        for (int i = 0; i < total; i += pageSize) {
//            int end = Math.min(i + pageSize, total);
//            log.info("Syncing from {} to {}", i, end);
//            questionEsDao.saveAll(questionEsDTOList.subList(i, end));
//        }
//        log.info("IncSyncQuestionToEs end, total {}", total);
//    }

    /**
     * 每分钟执行一次
     */
    @Scheduled(fixedRate = 60 * 1000)
    @DistributedLock(key = "testLock", leaseTime = 30000, waitTime =10000)
    public void run() {
        // 查询近 5 分钟内的数据
        long FIVE_MINUTES = 5 * 60 * 1000L;
        Date fiveMinutesAgoDate = new Date(new Date().getTime() - FIVE_MINUTES);
        List<Question> questionList = questionMapper.listQuestionWithDelete(fiveMinutesAgoDate);
        if (CollUtil.isEmpty(questionList)) {
            log.info("no inc question");
            return;
        }
        List<QuestionEsDTO> questionEsDTOList = questionList.stream()
                .map(QuestionEsDTO::objToDto)
                .collect(Collectors.toList());
        final int pageSize = 500;
        int total = questionEsDTOList.size();
        log.info("IncSyncQuestionToEs start, total {}", total);
        for (int i = 0; i < total; i += pageSize) {
            int end = Math.min(i + pageSize, total);
            log.info("sync from {} to {}", i, end);
            questionEsDao.saveAll(questionEsDTOList.subList(i, end));
        }
        log.info("IncSyncQuestionToEs end, total {}", total);
    }



//    public void start() {
//        // 启动任务调度
//        scheduleTask();
//    }
//    // 时间轮实例：时间间隔为100毫秒，每个时间片的精度为100毫秒
//    private static final HashedWheelTimer timer = new HashedWheelTimer(100, TimeUnit.MILLISECONDS);
//    private void scheduleTask() {
//        timer.newTimeout(new TimerTask() {
//            @Override
//            public void run(Timeout timeout) {
//                // 分布式锁，确保任务不会重复执行
//                boolean lockAcquired = acquireDistributedLock("testLock", 10000, 30000); // 10秒等待，30秒过期
//                if (!lockAcquired) {
//                    // 没有获取到锁，重新调度任务
//                    scheduleTask();
//                    return;
//                }
//
//                try {
//                    // 执行任务逻辑
//                    executeSyncTask();
//                } finally {
//                    // 释放分布式锁
//                    releaseDistributedLock("testLock");
//                }
//
//                // 重新调度下一次任务
//                scheduleTask();
//            }
//        }, 1, TimeUnit.MINUTES); // 设置 1 分钟后触发任务
//    }
}